﻿using Amazon;
using Sustainalytics.AwsS3.Client;
using Sustainalytics.ReportGenerator.BL;
using Sustainalytics.Synchronization.Interface;
using Sustainalytics.Utils.Configuration;
using System;
using System.Configuration;
using System.Linq;
using System.Net;
using System.Threading.Tasks;

namespace Sustainalytics.ClientDW.Synchronization
{
    public class GeneratePdfReportSyncStep : ISyncStep
    {
        private IPDFMachineManagement _machineManager;
        private readonly int _bulkSize;
        private readonly IS3Client _s3client;

        public SyncStepOrder ExecutionOrder => SyncStepOrder.GeneratePDFReports;

        public GeneratePdfReportSyncStep()
        {
            _bulkSize = 500;

            _s3client = new S3Client(new S3ClientSettings()
            {
                AccessKey = SettingsHelper.Read("accesKeyId", "AKIAJKGZZMOFAVOVLHJA"),
                SecretAccessKey = SettingsHelper.Read("awsSecretKey", "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"),
                ServiceEndPoint = SettingsHelper.Read("s3ServiceEndPoint", "https://s3-eu-west-1.amazonaws.com/")
            });
        }

        public SyncContext Start(SyncContext syncContext)
        {
            var mainMachine = SettingsHelper.Read("PDF_MachineId", "i-005bb5058f07df3ac");
            var accesKeyId = SettingsHelper.Read("PDFAccesKeyId", "AKIAJKGZZMOFAVOVLHJA");
            var secretKey = SettingsHelper.Read("PDFAWSSecretKey", "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");
            var regionName = SettingsHelper.Read("PDFAWSRegion", RegionEndpoint.EUWest1.SystemName);
            var region = RegionEndpoint.GetBySystemName(regionName);

            this._machineManager = new PDFMachineManagement(mainMachine, accesKeyId, secretKey, region);

            syncContext.Log(string.Format("Starting AWS instance:{0}", mainMachine));

            this._machineManager.StartAWSInstanceAsync().Wait();

            PdfEmailLogger emailSender = new PdfEmailLogger();

            var numberOfRetries = SettingsHelper.Read("GlobalRetryPolicyNumberOfRetries", 5);
            var secondsDelay = SettingsHelper.Read<double>("PdfGenerationServiceWaitTimeInSeconds", 60);

            var running = RetryPolicy.DoAsync(
                async () => await this._machineManager.GetAWSInstanceStateAsync().ConfigureAwait(false) == MachineState.Running,
                (int)(secondsDelay * 1000),
                numberOfRetries).Result;

            if (!running)
            {
                string message = string.Format("Unable to start Pdf Generation Machine after {0} number of retries with a wait period of {1} seconds!", numberOfRetries, secondsDelay);
                syncContext.Log(message);
                emailSender.SendEmailLog(string.Format("Unable to start Pdf Generation machine - {0}", Dns.GetHostName()));
            }

            //GCCS if quarter has changes
            var hasChanges = (syncContext.PreviousChanges.ToList()).Exists(x => x.AffectedKey == "Global Compact Documents Updated");

            var url = SettingsHelper.Read("pdfservurl", "http://52.208.68.121/pdfgenerationserv/");

            syncContext.Log(string.Format("Send pdf report request:{0}", url));

            var pdfClient = new PDFGeneratorHttpClient(url);

            var serviceReachable = RetryPolicy.DoAsync(
                async () => (await pdfClient.GetReportingStatusAsync().ConfigureAwait(false)).IsSuccessStatusCode,
                (int)(secondsDelay * 1000),
                numberOfRetries).Result;

            if (!serviceReachable)
            {
                string message = string.Format("Unable to start Pdf Generation Service after {0} number of retries with a wait period of {1} seconds!", numberOfRetries, secondsDelay);
                syncContext.Log(message);
                emailSender.SendEmailLog(string.Format("Pdf Generation service unreachable - {0}", Dns.GetHostName()));
            }

            if (running && serviceReachable)
            {
                syncContext.Log("Pdf generation started");

                // generating pdf without waiting for response
                // email will be sent when finished or error
                new TaskFactory().StartNew(() => pdfClient.StartGeneration(syncContext.GAConnectionStrings, hasChanges));
            }

            return syncContext;
        }
    }
}
